/*
 * @Description:
 * @FilePath: upload.js
 */
const chokidar = require('chokidar');
const log = require('electron-log');
const schedule = require('node-schedule');
const _ = require('lodash');
const path = require('path');
const Store = require('electron-store');

const fileTransferHelper = require('./fileTransferHelper');
const configManager = require('./config');
const getUserDataPath = require('./getUserDataPath');

const syncUpFileCheck = require('./syncFile');

const store = new Store({
    name: 'sync',
    cwd: getUserDataPath(),
});
const user = store.get('user');
const syncFolder = configManager.getLocal().folderPath;

log.info('上传线程文件已加载....');

process.parentPort.on('message', (e) => {
    let tempAddList = [];
    let tempChangeList = [];
    let tempDeleteList = [];
    const port = e.ports[0];

    async function doUpload(port, type) {
        const syncUpFile = new syncUpFileCheck();
        const taskList = await syncUpFile.getAllList();

        log.info(taskList);

        let resultAdd = syncUpFile.checkAddList(tempAddList, []);
        let resultChange = syncUpFile.checkChangeList(tempChangeList);

        log.info('当前变更的文件');
        log.info({ resultChange });
        log.info('当前新增的文件');
        log.info({ resultAdd });
        const result = resultChange.concat(resultAdd);
        if (result.length) {
            port.postMessage({
                type: 'file:upload:start',
                loading: true,
            });
            log.info('同步上传了文件' + result.length + '份文件');
            syncUpFile.createUploadTask(result, fileTransferHelper, port);
            tempChangeList = [];
            tempAddList = [];
            resultAdd = [];
            resultChange = [];
        } else {
            port.postMessage({
                type: 'file:upload:start',
                loading: false,
            });
            if (type) {
                port.postMessage({
                    type: 'file:upload:empty',
                });
            }
        }
    }

    fileTransferHelper.createServiceInstance({ uploadPort: port });
    port.on('message', (e) => {
        if (e.data.changePath) {
            log.info('old:' + syncFolder);
            log.info('new:' + configManager.getLocal().folderPath);
            watcher.unwatch(syncFolder);
            watcher.add(configManager.getLocal().folderPath);
            tempAddList = [];
            tempChangeList = [];
            tempDeleteList = [];
        } else {
            log.info('上传任务手动启动....');
            doUpload(port, true);
        }
    });

    log.info('上传线程启动...');
    // const rule = '*/59 * * * * *';
    const rule = '0 0 0/2 * * ?';

    const job = schedule.scheduleJob(rule, () => {
        console.log('任务进行中...');
        doUpload(port, false);
    });

    const watcher = chokidar.watch(syncFolder, {
        ignored: /(^|[\/\\])\../,
        ignoreInitial: true,
        persistent: true,
    });

    const rule2 = '*/5 * * * * *';
    const jobDelete = schedule.scheduleJob(rule2, async() => {
        if (tempDeleteList.length) {
            console.log('监测删除');
            const syncUpFile = new syncUpFileCheck();
            const taskList = await syncUpFile.getAllList();
            let resultDelete = syncUpFile.checkUnlinkList(tempDeleteList);
            log.info({ resultDelete });
            if (resultDelete.length) {
                const res = await syncUpFile.deleteFileStatus(resultDelete, port);
                if (res) {
                    tempDeleteList = [];
                    resultDelete = [];
                }
            }
        }
    });

    function checkStartFiles(list) {
        //  启动检测文件新增删除
        const checkStart = new syncUpFileCheck();
        checkStart.checkStartService(list).then((res) => {
            const { addFiles, deleteFiles } = res;
            if (addFiles.length) {
                port.postMessage({
                    type: 'file:upload:start',
                    loading: true,
                });
                checkStart.createUploadTask(addFiles, fileTransferHelper, port);
            }
            if (deleteFiles.length) {
                checkStart.deleteFileStatus(deleteFiles, port);
            }
        });
    }


    watcher.on('ready', () => {
        let list = [];
        if(syncFolder){
            const watchedPaths = watcher.getWatched();
            Object.keys(watchedPaths).forEach((dir) => {
                watchedPaths[dir].forEach((file) => {
                    let filePath = path.join(dir, file);
                    list.push(filePath);
                });
            });
            checkStartFiles(list);
        }
    }).on('add', (filePath) => {
            if (
                filePath.lastIndexOf('.tmp') == -1 &&
                filePath.lastIndexOf('.download') === -1 &&
                filePath.lastIndexOf('~$') === -1
            ) {
                let list = tempAddList.map((td) => td.filePath);
                if (list.indexOf(filePath) == -1) {
                    tempAddList.push({
                        filePath,
                    });
                }
            } else {
                log.info('异常副本文件' + filePath);
            }
        })
        .on('change', (filePath) => {
            log.info('change文件' + filePath);

            if (
                filePath.lastIndexOf('.tmp') == -1 &&
                filePath.lastIndexOf('.download') === -1 &&
                filePath.lastIndexOf('~$') === -1
            ) {
                tempChangeList.push({
                    filePath,
                });
            } else {
                log.info('异常更新副本文件' + filePath);
            }
        })
        .on('unlink', (filePath) => {
            if (
                filePath.lastIndexOf('.tmp') == -1 &&
                filePath.lastIndexOf('.download') === -1 &&
                filePath.lastIndexOf('~$') === -1
            ) {
                tempDeleteList.push({
                    filePath,
                    nodeType: 101,
                });
            }
        })
        .on('unlinkDir', (filePath) => {
            log.info('文件夹删除:' + filePath);

            // 去除新增文件里的删除
            tempAddList = tempAddList.filter((td) => td.filePath != filePath);
            tempChangeList = tempChangeList.filter((td) => td.filePath != filePath);
            tempDeleteList.push({
                filePath,
                nodeType: 100,
            });
        });

    port.start();
});

// 必要的全局错误捕获
process.on('uncaughtException', (error) => {
    log.error(error.stack || JSON.stringify(error));
});
